package controller

import (
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"poker/model"
	"poker/utils"
	"sort"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

const token = "xjjzhenren2025"

// 收到GET请求
func TestPaySuccessCallback(c *gin.Context) {
	info := model.OrderInfo{}
	info.Timestamp = c.Query("timestamp")
	info.Nonce = c.Query("nonce")
	info.Msg = c.Query("msg")
	info.Signature = c.Query("signature")
	info.Echostr = c.Query("echostr")

	sortedString := make([]string, 0, 4)
	sortedString = append(sortedString, token)
	sortedString = append(sortedString, info.Timestamp)
	sortedString = append(sortedString, info.Nonce)
	sortedString = append(sortedString, info.Msg)
	// 需要对这些参数按字符串自然大小进行排序
	sort.Strings(sortedString)
	// 使用SHA1算法
	h := sha1.New()
	h.Write([]byte(strings.Join(sortedString, "")))

	bs := h.Sum(nil)
	_signature := fmt.Sprintf("%x", bs)

	// signature 一致表示请求来源于 字节小程序服务端
	if _signature == info.Signature {
		c.String(http.StatusOK, info.Echostr)
		return
	}

	c.JSON(http.StatusUnauthorized, gin.H{"status": "auth error"})
}

func PaySuccessCallback(c *gin.Context) {
	var oi model.OrderInfo
	err := c.BindJSON(&oi)
	if err != nil {
		log.Println("BindJSON error", err.Error())
		c.JSON(http.StatusAccepted, gin.H{"status": "unsuccess"})
		return
	}

	var ospi model.OrderSuccessPayInfo
	err = json.Unmarshal([]byte(oi.Msg), &ospi)
	if err != nil {
		log.Println("Unmarshal error", err.Error())
		c.JSON(http.StatusAccepted, gin.H{"status": "fail"})
	}

	order := model.Order{}
	order.UpdateDate = time.Now().Format("2006/01/02 15:04:05")
	order.ExtraInfo = ospi.CpExtra
	order.AppID = ospi.Appid
	order.ID = ospi.CpOrderNo

	ext := map[string]interface{}{}
	json.Unmarshal([]byte(ospi.CpExtra), &ext)
	order.UID = ext["uid"].(string)

	if err := order.Save(); err != nil {
		c.JSON(http.StatusAccepted, gin.H{"msg": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": "success"})

	reqData := model.UploadPayInfoRequest{}
	reqData.GoodsName = ext["goodName"].(string)
	reqData.GoodsId = ext["goodsId"].(string)
	reqData.OrderId = ospi.CpOrderNo
	reqData.GoodsAmount = int(ext["price"].(float64))
	reqData.Param = ospi.CpExtra
	reqData.UserId = ext["uid"].(string)
	reqData.PhoneSystem = ext["phoneSystem"].(string)
	reqData.PlaceTime = oi.Timestamp
	reqData.UserName = ext["userName"].(string)
	reqData.OpenId = ext["uid"].(string)
	reqData.AppId = ospi.Appid
	UploadPayInfo(reqData)
}

func UploadPayInfo(reqData model.UploadPayInfoRequest) {
	// 将请求数据转换为 JSON 字符串
	jsonData, err := json.Marshal(reqData)
	if err != nil {
		log.Printf("Failed to marshal request data: %v\n", err)
		return
	}

	// 创建 HTTP 客户端
	client := &http.Client{}
	// 创建 POST 请求
	req, err := http.NewRequest("POST", "https://darknight.games/ks/upload_pay_info", bytes.NewBuffer(jsonData))
	if err != nil {
		log.Printf("Failed to create request: %v\n", err)
		return
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")

	// 发起请求
	resp, err := client.Do(req)
	if err != nil {
		log.Printf("Failed to send request: %v\n", err)
		return
	}
	defer resp.Body.Close()

	// 读取响应内容
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Failed to read response body: %v\n", err)
		return
	}

	// 输出响应内容
	log.Println("UploadPayInfo Response:", resp.Status, string(respBody))
}

func GetBalance(c *gin.Context) {
	req := model.GetBalanceRequest{}
	err := c.BindJSON(&req)
	if err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}

	pay_key, err := utils.LoadKey(req.AppID, "./conf/keys.txt")
	if err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}
	req.AccessToken = model.GetAccessToken(req.AppID)
	// 生成签名
	uri := "/api/apps/game/wallet/get_balance"
	method := "POST"
	req.Ts = time.Now().Unix()
	params := map[string]string{
		"openid":       req.OpenID,
		"appid":        req.AppID,
		"zone_id":      req.ZoneID,
		"access_token": req.AccessToken,
		"ts":           fmt.Sprintf("%d", req.Ts),
		"pf":           req.Pf,
	}
	mpSig := utils.GenerateSignature(pay_key, params, uri, method)
	req.Mp_sig = mpSig

	// 将请求体序列化为 JSON
	body, err := json.Marshal(req)
	if err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}

	// 构造 HTTP 请求
	url := "https://developer.toutiao.com/api/apps/game/wallet/get_balance"
	request, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
	if err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}

	// 设置请求头
	request.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err = io.ReadAll(resp.Body)
	if err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}

	// 解析响应体
	var response model.GetBalanceResponse
	if err := json.Unmarshal(body, &response); err != nil {
		c.String(http.StatusAccepted, err.Error())
		return
	}

	// 检查错误码
	if response.ErrCode != 0 {
		c.String(http.StatusAccepted, response.ErrMsg)
	}

	c.JSON(http.StatusOK, gin.H{"data": response})
}
